package lol.clann.bukkit.pluginboot.config.jackson.entity;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import lol.clann.bukkit.pluginboot.util.EntityUtils;
import lol.clann.bukkit.pluginboot.util.NBTUtils;
import lol.clann.clannboot.annotation.inject.Inject;
import lol.clann.clannboot.annotation.svc.PostInstance;
import lol.clann.clannboot.annotation.svc.Service;
import lol.clann.clannboot.config.jackson.Jackson;
import lol.clann.clannboot.config.jackson.fill.BaseJsonDeserializer;
import lol.clann.clannboot.util.JsonUtils;
import org.bukkit.entity.Entity;

import java.io.IOException;

/**
 * Entity只能序列化,不能反序列化
 * 可以手动创建Entity对象,把json转换成nbt,进行fill操作
 *
 * @author pyz
 * @date 2018/10/12 下午10:25
 */
@Service(priority = Integer.MAX_VALUE - 100)
public class EntityRegister {
    @Inject
    private EntityUtils entityUtils;
    @Inject
    private JsonUtils jsonUtils;

    @PostInstance
    private void init() {
        Jackson.addSerializer(Entity.class, new JsonSerializer<Entity>() {
            @Override
            public void serialize(Entity value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
                Object tag = entityUtils.toCompound(value);
                gen.writeObject(tag);
            }
        });
        Jackson.addDeserializer(Entity.class, new BaseJsonDeserializer<Entity>() {
            @Override
            protected Entity create(JsonParser p, DeserializationContext context) throws IOException, JsonProcessingException {
                throw new UnsupportedOperationException();
            }

            @Override
            protected Entity fill(Entity value, JsonParser p, DeserializationContext context) throws IOException, JsonProcessingException {
                Object tag = jsonUtils.readValue(p, NBTUtils.classNBTTagCompound.getHandle());
                entityUtils.fill(value, tag);
                return value;
            }
        });
        Jackson.addSerializer(EntityUtils.classNMSEntity.getHandle(), new JsonSerializer<Object>() {
            @Override
            public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
                Object tag = entityUtils.toCompound(value);
                gen.writeObject(tag);
            }
        });
        Jackson.addDeserializer(EntityUtils.classNMSEntity.getHandle(), new BaseJsonDeserializer<Object>() {
            @Override
            protected Object create(JsonParser p, DeserializationContext context) throws IOException, JsonProcessingException {
                throw new UnsupportedOperationException();
            }

            @Override
            protected Object fill(Object value, JsonParser p, DeserializationContext context) throws IOException, JsonProcessingException {
                Object tag = jsonUtils.readValue(p, NBTUtils.classNBTTagCompound.getHandle());
                entityUtils.fill(value, tag);
                return value;
            }
        });
    }
}
